package cn.hd01.web.controller;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.google.common.io.Files;
import com.google.zxing.client.result.BizcardResultParser;

import cn.hd01.common.BaseConstant;
import cn.hd01.common.BaseConstant.CustomerType;
import cn.hd01.common.BaseConstant.IsBalance;
import cn.hd01.common.BaseConstant.backendType;
import cn.hd01.common.PayType;
import cn.hd01.common.Payee;
import cn.hd01.export.COrderRowProcess;
import cn.hd01.export.ImporterDelegate;
import cn.hd01.export.impl.ExcelExporter;
import cn.hd01.export.result.ImportResult;
import cn.hd01.export.result.ResultListener;
import cn.hd01.model.IsBalanceModel;
import cn.hd01.repository.entity.BalanceReport;
import cn.hd01.repository.entity.COrder;
import cn.hd01.repository.entity.COrderPayment;
import cn.hd01.repository.entity.Customer;
import cn.hd01.repository.entity.Dictionary;
import cn.hd01.repository.entity.DistributorDetails;
import cn.hd01.repository.entity.DistributorLevel;
import cn.hd01.repository.entity.OrderProduct;
import cn.hd01.repository.entity.PaymentReport;
import cn.hd01.repository.entity.PaymentReportSummary;
import cn.hd01.repository.entity.Product;
import cn.hd01.repository.entity.User;
import cn.hd01.service.COrderPaymentService;
import cn.hd01.service.COrderService;
import cn.hd01.service.CustomerService;
import cn.hd01.service.DictionaryService;
import cn.hd01.service.DistributorDetailsService;
import cn.hd01.service.DistributorLevelService;
import cn.hd01.service.OrderProductService;
import cn.hd01.service.ProductService;
import cn.hd01.service.UserService;
import cn.hd01.sms.SmsService;
import cn.hd01.util.CommonUtil;
import cn.hd01.util.DictionaryType;
import cn.hd01.web.auth.Auth;
import cn.hd01.web.util.WebConstant;
import cn.hd01.web.util.WebException;

@Controller
@RequestMapping("/cOrder")
@Auth
public class COrderController {
	
	@Autowired
	private ImporterDelegate importer;
	
	@Autowired
	private ExcelExporter excelExporter;
	
	@Autowired
	private COrderService cOrderService;
	
	@Autowired
	private COrderPaymentService cOrderPaymentService;
	
	@Autowired
	private DistributorLevelService distributorLevelService;
	
	@Autowired
	private CustomerService customerService;
	
	@Autowired
	private SmsService smsService;
	
	@Autowired
	private DictionaryService dictionaryService;
	
	@Autowired
	private ProductService productService;
	
	@Autowired
	private UserService userService;
	
	@Autowired
	private OrderProductService orderProductService;
	
	@Autowired
	private DistributorDetailsService distributorDetailsService;
	
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
	
	private DecimalFormat    df   = new DecimalFormat("######0.00");    
	
	private DecimalFormat    df2   = new DecimalFormat("#");    
	
	@RequestMapping(method = RequestMethod.GET)
	public String index(Model m, HttpServletRequest request) {
		common(m, request);
		return "cOrder";
	}
	
	@RequestMapping(path = "/toOrder", method = RequestMethod.GET)
	public String toOrder(Model m, HttpServletRequest request) {
		common(m, request);
		return "cOrder";
	}
	
	@RequestMapping(path = "/detail/{financeOrderNo}", method = RequestMethod.GET)
	public String toOrderDetail(Model m, @PathVariable("financeOrderNo") String financeOrderNo, HttpServletRequest request) {
		COrder cOrder = cOrderService.findByFinanceOrderNo(financeOrderNo);
		List<OrderProduct> list = orderProductService.findByOrderId(cOrder.getId());
		BigDecimal totalAmount = BigDecimal.ZERO;
		//,臻颜术,CCT-丰额,1,59800,2;
		if(!CollectionUtils.isEmpty(list)){
			for(OrderProduct product: list){
				Product currProduct = productService.findOne(product.getProductId());
				if(currProduct != null){
					Product parentProduct = productService.findOne(currProduct.getParentId());
					if(parentProduct != null){
						product.setParentName(parentProduct.getName());
						totalAmount = totalAmount.add(new BigDecimal(product.getProductSalePrice()));
					}
				}
			}
		}
		StringBuffer customerName = new StringBuffer(cOrder.getCustomerName() + "(" + cOrder.getDistributorName());
		
		DistributorDetails details = distributorDetailsService.findByDistributorId(cOrder.getDistributorId());
		if(details != null){
			cOrder.setDistributorShopName(details.getShopName());
			customerName.append(details.getShopName()).append(")");
		}
		cOrder.setCustomerName(customerName.toString());
		cOrder.setTotalAmount(totalAmount);
		m.addAttribute("cOrder", cOrder);
		m.addAttribute("list", list);
		return "cOrderDetail";
	}
	
	private void common(Model m, HttpServletRequest request){
		List<IsBalanceModel> list = new ArrayList<IsBalanceModel>();
		list.add(new IsBalanceModel(IsBalance.BALANCE_DOWN_TEXT, IsBalance.BALANCE_DOWN));
		list.add(new IsBalanceModel(IsBalance.BALANCE_WAIT_TEXT, IsBalance.BALANCE_WAIT));
		m.addAttribute("isBalanceList", list);
		
		String isBalance = request.getParameter("isBalance");
		if(!StringUtils.isEmpty(isBalance)) {
			m.addAttribute("isBalanceStr", isBalance);
		}
		
		m.addAttribute("payTypeList", Arrays.asList(PayType.values()));
		m.addAttribute("payeeList", Arrays.asList(Payee.values()));
		String buttonId = request.getParameter("buttonId");
		m.addAttribute("buttonId", buttonId);
	}
	
	@RequestMapping(path = "/paymentReport", method = RequestMethod.GET)
	public String paymentReport(Model m, HttpServletRequest request) {
		List<IsBalanceModel> list = new ArrayList<IsBalanceModel>();
		list.add(new IsBalanceModel(IsBalance.BALANCE_DOWN_TEXT, IsBalance.BALANCE_DOWN));
		list.add(new IsBalanceModel(IsBalance.BALANCE_WAIT_TEXT, IsBalance.BALANCE_WAIT));
		m.addAttribute("isBalanceList", list);
		
		return "paymentReport";
	}
	
	@ResponseBody
	@RequestMapping(path = "/paymentReport/list", method = RequestMethod.GET)
	private Page<PaymentReport> paymentReportList(COrder c, @PageableDefault Pageable pageable, HttpServletRequest req) {
		Page<COrder> orderPage =  cOrderService.findAll(c, pageable);
		List<COrder> list = orderPage.getContent();
		List<PaymentReport> reportList = new ArrayList<PaymentReport>(list.size());
		
		String today = sdf.format(new Date());
		for(COrder order : list){
			PaymentReport report = new PaymentReport();
			report.setOrderId(order.getId());
			report.setAdvicer(order.getServantName());
			report.setCustomerName(order.getCustomerName());
			report.setDistributorName(order.getDistributorName());
			report.setOrderDate(order.getCreateTime());
			report.setServant(order.getServantName());
			report.setDetails(order.getProjectName());
			List<COrderPayment> paymentList = cOrderPaymentService.findByOrderId(order.getId());
			Map<String, BigDecimal> map = PayType.getMap();
			BigDecimal todayAmount = BigDecimal.ZERO;
			BigDecimal allAmount = BigDecimal.ZERO;
			for(COrderPayment pay : paymentList){
				BigDecimal amount = map.get(pay.getPayType());
				map.put(pay.getPayType(), amount.add(pay.getAmount()));
				if(today.equals(sdf.format(pay.getPayTime()))){
					todayAmount = todayAmount.add(pay.getAmount());
				}
				allAmount.add(amount);
			}
			report.setAllAmount(allAmount);
			report.setTodayAmount(todayAmount);
			report.setAlipay(map.get(PayType.ALIPAY.getCode()));
			report.setCash(map.get(PayType.CASH.getCode()));
			report.setCompanyTransfer(map.get(PayType.COMPANY_TRANSFER_9980.getCode()));
			report.setPosqj(map.get(PayType.POS_QJ_1.getCode()));
			report.setPosym(map.get(PayType.POS_OM.getCode()));
			report.setShop(map.get(PayType.SHOP.getCode()));
			report.setSqb(map.get(PayType.SQB.getCode()));
			report.setWx(map.get(PayType.WX.getCode()));
			
			reportList.add(report);
		}
		Page<PaymentReport> pageList = new PageImpl<PaymentReport>(reportList, pageable, orderPage.getTotalElements());
		return pageList; 
	}
	
	@ResponseBody
	@RequestMapping(path = "/paymentReport/summary", method = RequestMethod.GET)
	private Page<PaymentReportSummary> paymentReportSummary(COrder c, @PageableDefault Pageable pageable, HttpServletRequest req) {
		List<COrder> orderList =  cOrderService.findAll(c);
		List<PaymentReportSummary> reportList = new ArrayList<PaymentReportSummary>(3);
		PaymentReportSummary summary = new PaymentReportSummary("总业绩合计");
		PaymentReportSummary feeSummary = new PaymentReportSummary("刷卡手续费合计");
		PaymentReportSummary leftSummary = new PaymentReportSummary("实际回款:扣刷卡手续费");
		
		String today = sdf.format(new Date());
		for(COrder order : orderList){
			List<COrderPayment> paymentList = cOrderPaymentService.findByOrderId(order.getId());
			Map<String, BigDecimal> map = PayType.getMap();
			Map<String, BigDecimal> feeMap = PayType.getMap();
			
			BigDecimal todayAmount = BigDecimal.ZERO;
			for(COrderPayment pay : paymentList){
				BigDecimal amount = map.get(pay.getPayType());
				BigDecimal feeAmount = feeMap.get(pay.getPayType());
				map.put(pay.getPayType(), amount.add(pay.getAmount()));
				feeMap.put(pay.getPayType(), feeAmount.add(pay.getFeeAmount()));
				if(today.equals(sdf.format(pay.getPayTime()))){
					todayAmount = todayAmount.add(pay.getAmount());
				}
			}
			summary.setTodayAmount(summary.getTodayAmount().add(todayAmount));
			summary.setAlipay(summary.getAlipay().add(map.get(PayType.ALIPAY.getCode())));
			summary.setCash(summary.getCash().add(map.get(PayType.CASH.getCode())));
			summary.setCompanyTransfer(summary.getCompanyTransfer().add(map.get(PayType.COMPANY_TRANSFER_9980.getCode())));
			summary.setPosqj(summary.getPosqj().add(map.get(PayType.POS_QJ_1.getCode())));
			summary.setPosym(summary.getPosym().add(map.get(PayType.POS_OM.getCode())));
			summary.setShop(summary.getShop().add(map.get(PayType.SHOP.getCode())));
			summary.setSqb(summary.getSqb().add(map.get(PayType.SQB.getCode())));
			summary.setWx(summary.getWx().add(map.get(PayType.WX.getCode())));
			
			feeSummary.setAlipay(feeSummary.getAlipay().add(feeMap.get(PayType.ALIPAY.getCode())));
			feeSummary.setCash(feeSummary.getCash().add(feeMap.get(PayType.CASH.getCode())));
			feeSummary.setCompanyTransfer(feeSummary.getCompanyTransfer().add(feeMap.get(PayType.COMPANY_TRANSFER_9980.getCode())));
			feeSummary.setPosqj(feeSummary.getPosqj().add(feeMap.get(PayType.POS_QJ_1.getCode())));
			feeSummary.setPosym(feeSummary.getPosym().add(feeMap.get(PayType.POS_OM.getCode())));
			feeSummary.setShop(feeSummary.getShop().add(feeMap.get(PayType.SHOP.getCode())));
			feeSummary.setSqb(feeSummary.getSqb().add(feeMap.get(PayType.SQB.getCode())));
			feeSummary.setWx(feeSummary.getWx().add(feeMap.get(PayType.WX.getCode())));
		}
		
		buildLeftSummary(summary, feeSummary, leftSummary);
		
		reportList.add(summary);
		reportList.add(feeSummary);
		reportList.add(leftSummary);
		Page<PaymentReportSummary> pageList = new PageImpl<PaymentReportSummary>(reportList, pageable, 3);
		return pageList; 
	}
	
	private void buildLeftSummary(PaymentReportSummary summary, PaymentReportSummary feeSummary,  PaymentReportSummary leftSummary){
		leftSummary.setPosqj(summary.getPosqj().subtract(feeSummary.getPosqj()));
		leftSummary.setPosym(summary.getPosym().subtract(feeSummary.getPosym()));
		leftSummary.setWx(summary.getWx().subtract(feeSummary.getWx()));
		leftSummary.setAlipay(summary.getAlipay().subtract(feeSummary.getAlipay()));
		leftSummary.setSqb(summary.getSqb().subtract(feeSummary.getSqb()));
		leftSummary.setCash(summary.getCash());
		leftSummary.setShop(summary.getShop());
		leftSummary.setCompanyTransfer(summary.getCompanyTransfer());
	}
	
	@RequestMapping(path = "/balanceReport", method = RequestMethod.GET)
	public String balanceReport(Model m, HttpServletRequest request) {
		return "balanceReport";
	}
	
	@ResponseBody
	@RequestMapping(path = "/balanceReport/list", method = RequestMethod.GET)
	private Page<BalanceReport> balanceReportList(COrder c, @PageableDefault Pageable pageable, HttpServletRequest req) {
		Page<COrder> orderPage =  cOrderService.findAll(c, pageable);
		List<COrder> list = orderPage.getContent();
		List<BalanceReport> reportList = new ArrayList<BalanceReport>(list.size());
		
		Set<String> payeeSet = new HashSet<String>();
		for(COrder order : list){
			BalanceReport report = new BalanceReport();
			BeanUtils.copyProperties(order, report);
			List<COrderPayment> paymentList = cOrderPaymentService.findByOrderId(order.getId());
			BigDecimal payAmount = BigDecimal.ZERO;
			BigDecimal feeAmount = BigDecimal.ZERO;
			BigDecimal shopAmount = BigDecimal.ZERO;
			for(COrderPayment pay : paymentList){
				payAmount = payAmount.add(pay.getAmount());
				feeAmount = feeAmount.add(pay.getFeeAmount());
				payeeSet.add(pay.getPayee());
				if(Payee.SHOP.getCode().equals(pay.getPayee())){
					shopAmount = shopAmount.add(pay.getAmount());
				}
			}
			String allPayee = "";
			for(String payee : payeeSet){
				allPayee += payee + " "; 
			}
			report.setPayAmount(payAmount);
			report.setFeeAmount(feeAmount);
			report.setPayee(allPayee);
			if(!order.getAmount().equals(BigDecimal.ZERO) && !shopAmount.equals(BigDecimal.ZERO)){
				report.setDebtRatio(shopAmount.divide(order.getAmount(), 4, RoundingMode.HALF_UP));
			}
			reportList.add(report);
		}
		Page<BalanceReport> pageList = new PageImpl<BalanceReport>(reportList, pageable, orderPage.getTotalElements());
		return pageList; 
	}

	@ResponseBody
	@RequestMapping(path = "/list", method = RequestMethod.GET)
	private Page<COrder> find(COrder c, @PageableDefault Pageable pageable, HttpServletRequest req) {
		Sort sort = new Sort(Direction.DESC, "createTime");
		Pageable page = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), sort);
		String servantId = req.getParameter("servantId");
		
		User loginUser = (User) req.getSession().getAttribute(WebConstant.USER_SESSION_NAME);
		Integer type = CommonUtil.getLoginUserType(loginUser);

		if(backendType.TEACHER.equals(type) || StringUtils.hasText(servantId)){
			
			Integer searchId = StringUtils.hasText(servantId) ? Integer.valueOf(servantId) : loginUser.getId();
			
			List<Integer> distributorIdList = customerService.findDistributorIdByServantId(searchId);
			if(CollectionUtils.isEmpty(distributorIdList)){
				return new PageImpl<COrder>(new ArrayList<COrder>());
			}else{
				c.setDistributorIdList(distributorIdList);
			}
		} 
		return cOrderService.findAll(c, page); 
	}
	
	@ResponseBody
	@RequestMapping(path = "/balance/{id}", method = RequestMethod.GET)
	private void balance(@PathVariable("id") Integer id) {
		cOrderService.balanceOrder(id);
	}
	

	@ResponseBody
	@RequestMapping(path = "/delete/{id}", method = RequestMethod.GET)
	private void delete(@PathVariable("id") Integer id) {
		COrder order = cOrderService.findOne(id);
		if(order == null){
			throw new WebException(HttpStatus.BAD_REQUEST, "订单不存在");
		} else if(BaseConstant.IsBalance.BALANCE_DOWN.equals(order.getIsBalance())){
			throw new WebException(HttpStatus.BAD_REQUEST, "订单状态为已结算，不能删除");
		}
		
		cOrderService.delete(id);
		orderProductService.deleteByOrderId(id);
		cOrderPaymentService.deleteByOrderId(id);;
	}

	@ResponseBody
	@RequestMapping(path = "/import", method = RequestMethod.POST)
	@Transactional
	private ImportResult importExcel(@RequestParam("file") MultipartFile file){
		try {
			
			File dest = new File(Files.createTempDir(), file.getOriginalFilename());
			file.transferTo(dest);

			ResultListener result = new ResultListener();
			COrderRowProcess cOrderRowProcess = new COrderRowProcess(result, cOrderService, distributorLevelService, smsService);
			importer.asyncImporter(dest, cOrderRowProcess);
			return result.getResult();
		} catch (Exception e) {
			throw new WebException(HttpStatus.BAD_REQUEST, e.getMessage());
		}
	}
	
	@RequestMapping(value="/export")
	public void export(HttpServletRequest res, COrder c, HttpServletRequest req, HttpServletResponse resp){
       try {
    	   resp.setHeader("content-type", "application/octet-stream");
 		   resp.setContentType("application/octet-stream");
 		   resp.setHeader("Content-Disposition", "attachment;filename=order.xls");
 		   COrderRowProcess cOrderRowProcess = new COrderRowProcess(new ResultListener(), cOrderService, distributorLevelService, smsService);
 		   
 		   User loginUser = (User) req.getSession().getAttribute(WebConstant.USER_SESSION_NAME);
 		   Integer type = CommonUtil.getLoginUserType(loginUser);

 		   if(backendType.TEACHER.equals(type)){
 				List<Integer> distributorIdList = customerService.findDistributorIdByServantId(loginUser.getId());
 				if(CollectionUtils.isEmpty(distributorIdList)){
 					throw new WebException(HttpStatus.BAD_REQUEST, "无数据可导出");
 				}else{
 					c.setDistributorIdList(distributorIdList);
 				}
 			}  		   
 		   cOrderRowProcess.setOrder(c);
 		   excelExporter.export(resp.getOutputStream(), cOrderRowProcess, "订单");
		} catch (Exception e) {
			throw new WebException(HttpStatus.BAD_REQUEST, e.getMessage());
		}
	}
	
	@RequestMapping(value="/download", method=RequestMethod.GET)  
	public void testDownload(HttpServletRequest res, HttpServletResponse resp) throws IOException{  
	  StringBuffer sb = new StringBuffer(ClassUtils.getDefaultClassLoader().getResource("").getPath());
	  sb.append(File.separator).append("static").append(File.separator).append("assets").append(File.separator).append("download").append(File.separator).append("template.xlsx");
	  File file = new File(sb.toString());
	  resp.setHeader("content-type", "application/octet-stream");
	  resp.setContentType("application/octet-stream");
	  resp.setHeader("Content-Disposition", "attachment;filename=" + file.getName());
	  byte[] buff = new byte[1024];
	  BufferedInputStream bis = null;
	  OutputStream os = null;
	  try {
		  os = resp.getOutputStream();
		  bis = new BufferedInputStream(new FileInputStream(file));
		  int i = bis.read(buff);
		  while (i != -1) {
			  os.write(buff, 0, buff.length);
			  os.flush();
			  i = bis.read(buff);
		  }
	  } catch (IOException e) {
		  e.printStackTrace();
	  } finally {
		  if (bis != null) {
			  try {
				  bis.close();
			  } catch (IOException e) {
				  e.printStackTrace();
			  }
		  }
	  }
	}  
	
	@RequestMapping(path = "/editOrder", method = RequestMethod.GET)
	public String editOrder(Model m, Integer orderId, HttpServletRequest request) {
		
		COrder cOrder = cOrderService.findOne(orderId);
		List<OrderProduct> list = orderProductService.findByOrderId(orderId);
		//查询产品列表
		List<Product> productList = productService.findProductList();
		//查询会员列表
		List<Customer> customerList =  new ArrayList<>();
		User loginUser = (User) request.getSession().getAttribute(WebConstant.USER_SESSION_NAME);
		Integer type = CommonUtil.getLoginUserType(loginUser);
		if(backendType.TEACHER.equals(type)){
			customerService.findCustomerList(CustomerType.DISTRIBUTOR,loginUser.getId());
		}else{
			customerList = customerService.findCustomerList(CustomerType.CUSTOMER);
			if(customerList != null){
				for(Object o : customerList){
					Object[] arr = (Object[]) o;
					Object recommRecommDisIdObj = arr[2];
					
					if(recommRecommDisIdObj != null){
						DistributorDetails details = distributorDetailsService.findByDistributorId((Integer) recommRecommDisIdObj);
						if(details != null) arr[1] += "(" + details.getShopName() + ")";
					}
				}
			}
		}
		
		StringBuffer productMsg = new StringBuffer();
		BigDecimal totalAmount = BigDecimal.ZERO;
		//,臻颜术,CCT-丰额,1,59800,2;
		if(!CollectionUtils.isEmpty(list)){
			for(OrderProduct product: list){
				Product currProduct = productService.findOne(product.getProductId());
				if(currProduct != null){
					Product parentProduct = productService.findOne(currProduct.getParentId());
					if(parentProduct != null){
						product.setParentName(parentProduct.getName());
						productMsg.append(",").append(parentProduct.getParentName()).append(",").append(currProduct.getName()).append(",").append(product.getOperationCount())
						.append(",").append(product.getProductSalePrice()).append(",").append(product.getProductId()).append(";");
						totalAmount = totalAmount.add(new BigDecimal(product.getProductSalePrice()));
					}
				}
			}
		}
		cOrder.setProductMsg(productMsg.toString());
		cOrder.setTotalAmount(totalAmount);
//		//查询渠道商
//		List<Customer> distributorList =  new ArrayList<>();
//		distributorList = customerService.findCustomerList("1","1");
	
//		m.addAttribute("distributorList", distributorList);
		m.addAttribute("orderProductList", list);
		m.addAttribute("cOrder", cOrder);
		m.addAttribute("customerList", customerList);
		m.addAttribute("productList", productList);
		return "editOrder";
	}
	
	@RequestMapping(path = "/addOrder", method = RequestMethod.GET)
	public String addOrder(Model m, HttpServletRequest request) {
		//查询产品列表
		List<Product> productList = productService.findProductList();
		//查询会员列表
		List<Customer> customerList =  new ArrayList<>();
		User loginUser = (User) request.getSession().getAttribute(WebConstant.USER_SESSION_NAME);
		Integer type = CommonUtil.getLoginUserType(loginUser);
		if(backendType.TEACHER.equals(type)){
			customerService.findCustomerList(CustomerType.DISTRIBUTOR,loginUser.getId());
		}else{
			customerList = customerService.findCustomerList(CustomerType.CUSTOMER);
			if(customerList != null){
				for(Object o : customerList){
					Object[] arr = (Object[]) o;
					Object recommRecommDisIdObj = arr[2];
					
					if(recommRecommDisIdObj != null){
						DistributorDetails details = distributorDetailsService.findByDistributorId((Integer) recommRecommDisIdObj);
						if(details != null) arr[1] += "(" + details.getShopName() + ")";
					}
				}
			}
		}
		
//		//查询渠道商
//		List<Customer> distributorList =  new ArrayList<>();
//		distributorList = customerService.findCustomerList("1","1");
	
//		m.addAttribute("distributorList", distributorList);
		m.addAttribute("customerList", customerList);
		m.addAttribute("productList", productList);
		return "addOrder";
	}
	
	@ResponseBody
	@RequestMapping(path = "/save", method = RequestMethod.POST)
	private void save(COrder order, DistributorDetails distributorDetails) {
		validateCustomer(order);
		
		if(order.getId() != null){
			orderProductService.deleteByOrderId(order.getId());
		}
		
		Customer customer = new Customer();
		customer.setId(order.getCustomerId());
		Customer cr = customerService.findOne(order.getCustomerId());
		order.setCustomerPhoneNo(cr.getPhoneNo());
		order.setCustomerId(cr.getId());
		order.setCustomerName(cr.getName());
		Integer distributorId = cr.getRecommendDistributorId();
		Customer distributor = null;
		if(distributorId!=null){
			distributor = customerService.findOne(distributorId);
			order.setDistributorId(distributor.getId());
			order.setDistributorName(distributor.getName());
			order.setDistributorPhoneNo(distributor.getPhoneNo());
		}else{
			throw new WebException(HttpStatus.BAD_REQUEST, "会员没有渠道商");
		}
		order.setServantId(cr.getServantId());
		order.setServantName(cr.getServantName());
		order.setIsBalance(IsBalance.BALANCE_WAIT);//未结算
		order.setUpdateTime(new Date());//插入时候报控制针
		order.setProductName(order.getProjectName());
		
		/*OrderProduct orderProduct = new OrderProduct();
		orderProduct.setOrderId(order.getId());
		orderProduct.setProductId(Integer.valueOf(id));
		orderProduct.setProductName(pName);
		orderProduct.setProductSalePrice(price);
		orderProduct.setCreateTime(new Date());
		orderProductService.save(orderProduct);*/
		
		String projectName = "";
		String[] productMsg = order.getProductMsg().split(";");
		List<OrderProduct> opList = new ArrayList<OrderProduct>();
		Double totalAmount = 0D;
		for(int i = 0; i < productMsg.length; i++){
			String[] productMsg2 = productMsg[i].split(",");
			OrderProduct orderProduct = new OrderProduct();
			for(int j = 0; j < productMsg2.length; j++){
				if(j == 2){
					projectName +=  productMsg2[j] + ",";
					orderProduct.setProductName(productMsg2[j]);
				} else if(j == 3){
					orderProduct.setOperationCount(Integer.valueOf(productMsg2[j]));
				} else if(j == 4){
					orderProduct.setProductSalePrice(Double.valueOf(productMsg2[j]));
					totalAmount += orderProduct.getProductSalePrice();
				} else if(j == 5){
					orderProduct.setProductId(Integer.valueOf(productMsg2[j]));
				}
			}
			orderProduct.setCreateTime(new Date());
			opList.add(orderProduct);
		}
		projectName = projectName.substring(0, projectName.lastIndexOf(","));
		/*<th>项目大类</th>
		<th>项名称</th>
		<th>次数</th>
		<th>金额</th>*/
		/*String projectName = "";
		String []productIds = order.getProjectName().split(",");
		if(productIds.length >= 1){
			for (String productId : productIds) {
				if(StringUtils.isEmpty(productId)) continue;
				Product p = productService.findOne(Integer.parseInt(productId));
				projectName += p.getName() + ",";
			}
		}
		projectName = projectName.substring(0, projectName.lastIndexOf(","));*/
		
//		String projectName = getProductName(order);
		order.setProjectName(projectName);
		order.setDistributorRebate(BigDecimal.ZERO);
		order.setRecommDistributorRebate(BigDecimal.ZERO);
		order.setServantRebate(BigDecimal.ZERO);
		DistributorLevel level = null;
		String errorText = "";
		if(distributor != null){
			List<DistributorLevel> levelList =distributorLevelService.findAll();
			level = findLevel(errorText, distributor.getLevelId(), levelList);
			
			order.setDistributorRebateRate(level.getRebateRate());
			//order.setDistributorRebate(order.getAmount().multiply(order.getDistributorRebateRate()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
			
			//服务老师设置与佣金
			if(distributor.getServantId() != null){
				User servantTeacher = userService.findOne(distributor.getServantId());
				
				if(servantTeacher != null){
					order.setServantId(servantTeacher.getId());
					order.setServantName(servantTeacher.getName());
				}
				
				List<Dictionary> dictList = dictionaryService.findByType(DictionaryType.SERVANT_REBATE_RATE);
				Dictionary servantDict = null;
				if(!CollectionUtils.isEmpty(dictList)){
				    servantDict = dictList.get(0);
				    
				    order.setServantRebateRate(new BigDecimal(servantDict.getValue()));
					//order.setServantRebate(order.getAmount().multiply(order.getServantRebateRate()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
				}
				
			}
			
		}
		Customer recommDistributor = null;
		if(distributor.getRecommendDistributorId() != null){
			recommDistributor = customerService.findOne(distributor.getRecommendDistributorId());	
		}
		//推荐渠道商佣金
		if(recommDistributor != null ){
			order.setRecommDistributorId(recommDistributor.getId());
			order.setRecommDistributorName(recommDistributor.getName());
			order.setRecommDistributorPhoneNo(recommDistributor.getPhoneNo());
			
			
			List<Dictionary> dictList = dictionaryService.findByType(DictionaryType.DISTRIBUTOR_REBATE_RATE);
			if(!CollectionUtils.isEmpty(dictList)){
				Dictionary dict = dictList.get(0);
				
				//推荐渠道商佣金
				BigDecimal rate = new BigDecimal(dict.getValue().trim());
				
				order.setRecommDistributorRebateRate(rate);
				//order.setRecommDistributorRebate(order.getAmount().multiply(rate).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
			}
			
		}
		//保存订单
		COrder o = cOrderService.save(order);
		saveOrderProductName(o, opList, totalAmount);
	}
	
	private String getProductName(COrder order){
		String result = "";
		String productName = order.getProductName();
		String productNames[] = productName.split(";");
		if(productNames.length >=1){
			for (String name : productNames) {
				if(StringUtils.isEmpty(name)) continue;
				String names[] = name.split("&");
				String id = names[0].split("=")[1];
				String pName = names[1].split("=")[1];
				String price = names[2].split("=")[1];
				result += pName + ",";
			}
			result = result.substring(0, result.lastIndexOf(","));
		}
		return result;
	}
	
	private void saveOrderProductName(COrder order, List<OrderProduct> list, Double totalAmount){
		BigDecimal a = new BigDecimal(totalAmount);
        BigDecimal f1 = BigDecimal.ZERO.compareTo(a) == 0 ? BigDecimal.ZERO : order.getAmount().divide(a, 4, RoundingMode.HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP);  
		for(OrderProduct op : list){
			op.setOrderId(order.getId());
			BigDecimal psp = new BigDecimal(op.getProductSalePrice());
			op.setDiscountSalePrice(psp.multiply(f1).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue());
			orderProductService.save(op);
		}
	}
	
	private void saveOrderProductName(COrder order){
		//计算产品折扣
		BigDecimal amount = order.getAmount();
		Double productAmount = 0d;
		String []productIds = order.getProductName().split(",");
		if(productIds.length >= 1){
			for (String productId : productIds) {
				if(StringUtils.isEmpty(productId)) continue;
				Product p = productService.findOne(Integer.parseInt(productId));
				productAmount = productAmount + p.getPrice();
			}
			Double discount = amount.doubleValue()/ productAmount;
			if(discount > 1d){
				discount = 1d;
			}
			for (String productId : productIds) {
				if(StringUtils.isEmpty(productId)) continue;
				Product p = productService.findOne(Integer.parseInt(productId));
				Integer id = p.getId();
				String pName = p.getName();
				Double price = p.getPrice()*discount;
				OrderProduct orderProduct = new OrderProduct();
				orderProduct.setOrderId(order.getId());
				orderProduct.setProductId(Integer.valueOf(id));
				orderProduct.setProductName(pName);
				orderProduct.setProductSalePrice(price);
				orderProduct.setCreateTime(new Date());
				orderProductService.save(orderProduct);
			}
			
		}
	}
	
//	private void saveOrderProductName(COrder order){
//		String result = "";
//		String productName = order.getProductName();
//		String productNames[] = productName.split(";");
//		if(productNames.length >=1){
//			for (String name : productNames) {
//				if(StringUtils.isEmpty(name)) continue;
//				String names[] = name.split("&");
//				String id = names[0].split("=")[1];
//				String pName = names[1].split("=")[1];
//				String price = names[2].split("=")[1];
//				OrderProduct orderProduct = new OrderProduct();
//				orderProduct.setOrderId(order.getId());
//				orderProduct.setProductId(Integer.valueOf(id));
//				orderProduct.setProductName(pName);
//				orderProduct.setProductSalePrice(Double.valueOf(price));
//				orderProduct.setCreateTime(new Date());
//				orderProductService.save(orderProduct);
//			}
//		}
//	}
	
	private DistributorLevel findLevel(String errorText, Integer levelId, List<DistributorLevel> levelList){
		for(DistributorLevel l : levelList){
			if(levelId == l.getId()){
				return l;
			}
		}

		errorText = "不存在渠道商权益，id为" + levelId + ", 新增订单失败";
		throw new WebException(HttpStatus.BAD_REQUEST, "不存在渠道商权益，id为" + levelId + ", 新增订单失败");
	}
	
	private void validateCustomer(COrder order){
		
		if(StringUtils.isEmpty(order.getAmount())){
			throw new WebException(HttpStatus.BAD_REQUEST, "项目金额不能为空");
		}
		
		if(StringUtils.isEmpty(order.getCustomerId()) || order.getCustomerId() == -1){
			throw new WebException(HttpStatus.BAD_REQUEST, "会员不能为空");
		}
		
//		if(StringUtils.isEmpty(order.getDistributorId()) || "-1".equals(order.getDistributorId())){
//			throw new WebException(HttpStatus.BAD_REQUEST, "渠道商不能为空");
//		}
		
		if(StringUtils.isEmpty(order.getCreateTime())){
			throw new WebException(HttpStatus.BAD_REQUEST, "项目时间不能为空");
		}
		
		COrder cOrder = cOrderService.findByFinanceOrderNo(order.getFinanceOrderNo());
		if((order.getId() == null && cOrder != null) ||
				(order.getId() != null && cOrder != null && !cOrder.getId().equals(order.getId()))){
			throw new WebException(HttpStatus.BAD_REQUEST, "财务单号已存在！");
		}
	}
	
	@RequestMapping(path = "/workReport", method = RequestMethod.GET)
	public String workReport(Model m, HttpServletRequest request) {
		//当月操作人数****人（和上述的操作记录挂钩，点击进入到操作记录的列表）
		Integer operatCountToday = cOrderService.countOperationByToday();
		//当月操作人数****人（和上述的操作记录挂钩，点击进入到操作记录的列表）
		Integer operatCount = cOrderService.countOperationByMonth();
		//今日业绩（今日录入项目的总额，点击跳转到订单的列表)
		Double achievementToday = cOrderService.sumAchievementToday();
		if(achievementToday == null){
			achievementToday = 0d;
		}
		
		//当月业绩
		Double achievementMonth = cOrderService.sumAchievementMonth();
		if(achievementMonth == null){
			achievementMonth = 0d;
		}
		
		//进度条：百分比（月度目标完成：实际金额和月度设置金额的比例）
		Double progressMonthly = cOrderService.progressMonthlyTarget();
		if(progressMonthly == null){
			progressMonthly =0d;
		}
	/*	if(progressMonthly >=100){
			progressMonthly =100d;
		}*/
		//K值总额****K值（未结算+已结算）渠道商佣金 按月统计
		//Double totalRebate = cOrderService.sumDistributorRebateRate(null);
		//已结算K值：*****K值
		//Double downRebate = cOrderService.sumDistributorRebateRate(IsBalance.BALANCE_DOWN);
		List<Object[]> rebateList = cOrderPaymentService.findRebate();
		BigDecimal downRebate = BigDecimal.ZERO;
		BigDecimal waitRebate = BigDecimal.ZERO;
		
		if(!CollectionUtils.isEmpty(rebateList)){
			downRebate = (BigDecimal) rebateList.get(0)[0]; 
			waitRebate = (BigDecimal) rebateList.get(0)[1];
		}
		
		//待结算K值：*****K值（客户已付款，但是未结算）
		//Double waitRebate = cOrderService.sumDistributorRebateRate(IsBalance.BALANCE_WAIT);
		BigDecimal totalRebate = downRebate.add(waitRebate);
		m.addAttribute("operatCountToday", df2.format(operatCountToday));
		m.addAttribute("achievementMonth", df2.format(achievementMonth));
		m.addAttribute("operatCount", operatCount);
		m.addAttribute("progressMonthly", df.format(progressMonthly));
		m.addAttribute("achievementToday", df2.format(achievementToday));
		m.addAttribute("totalRebate", df2.format(totalRebate));
		m.addAttribute("downRebate", df2.format(downRebate));
		m.addAttribute("waitRebate", df2.format(waitRebate));
		return "workReport";
	}
	
	@RequestMapping(path = "/productReport", method = RequestMethod.GET)
	public String productReport(Model m, HttpServletRequest request) {
		List<Product> productList = productService.findParentProductList();
		m.addAttribute("parentProductList", productList);
		return "productReport";
	}
	
	@ResponseBody
	@RequestMapping(path = "/productReportList", method = RequestMethod.GET)
	private Page<OrderProduct> productReportList(int sort, OrderProduct c, @PageableDefault Pageable pageable, HttpServletRequest req) {
		
		Page<OrderProduct> orderPage =  orderProductService.pageOrderList(sort, c, pageable);
		List<OrderProduct> orderProductList = orderPage.getContent();
		if(CollectionUtils.isEmpty(orderProductList)){
			return orderPage;
		}
		for (OrderProduct orderProduct : orderProductList) {
			Integer id = orderProduct.getProductId();
			orderProduct.setCount(orderProductService.getProductCount(id));
		}
		
		return orderPage; 
	}
	
	@ResponseBody
	@RequestMapping(path = "/pproductReportList", method = RequestMethod.GET)
	private Page<OrderProduct> pproductReportList(OrderProduct c, @PageableDefault Pageable pageable, HttpServletRequest req) {
		
		List<OrderProduct> parentProductList = orderProductService.findParentOrderList(c);
		Page<OrderProduct> pageList = new PageImpl<OrderProduct>(parentProductList, pageable, parentProductList.size());
		return pageList; 
	}

}
